package com.boarsoft.boar.batch.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.batch.biz.BatchExecutionBiz;
import com.boarsoft.boar.batch.biz.BatchInfoBiz;
import com.boarsoft.boar.batch.entity.BatchExecution;
import com.boarsoft.boar.batch.entity.BatchInfo;
import com.boarsoft.boar.batch.service.BatchDispatcher;
import com.boarsoft.boar.common.Constants;
import com.boarsoft.common.Authorized;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.common.util.BeanUtil;

@RestController
@RequestMapping("/execution")
public class BatchExecutionAction {

	@Autowired
	private BatchExecutionBiz batchExeBiz;
	@Autowired
	private BatchInfoBiz batchInfoBiz;

	@Autowired
	private ApplicationContext appCtx;

	private ReplyInfo<Object> getBatchDispatcher(String id) {
		BatchExecution be = batchExeBiz.get(id);
		if (be == null) {
			return new ReplyInfo<>(BatchExecution.ERROR_NOT_FOUND);
		}
		BatchInfo bi = null;
		if (Util.strIsNotEmpty(be.getInfoId())) {
			bi = batchInfoBiz.get(be.getInfoId());
		}
		if (bi == null) {
			return new ReplyInfo<>(BatchExecution.ERROR_MISSING_INFO);
		}
		BatchDispatcher bd = null;
		if (Util.strIsNotEmpty(bi.getImpl())) {
			if (appCtx.containsBean(bi.getImpl())) {
				bd = (BatchDispatcher) appCtx.getBean(bi.getImpl());
			}
		}
		if (bd == null) {
			return new ReplyInfo<>(Constants.WARN_INVALID, "impl");
		}
		return ReplyInfo.success(bd);
	}

	@RequestMapping("/resume.do")
	@Authorized(code = "batch.execution.resume")
	public ReplyInfo<Object> resume(String id) {
		if (Util.strIsEmpty(id)) {
			return new ReplyInfo<>(Constants.WARN_INVALID, "resume");
		}
		ReplyInfo<Object> bd = this.getBatchDispatcher(id);
		if (bd.isSuccess()) {
			int result = ((BatchDispatcher) bd.getData()).resume(id);
			return ReplyInfo.success(result);
		}
		return null;
	}

	@RequestMapping("/redo.do")
	@Authorized(code = "batch.execution.redo")
	public ReplyInfo<Object> redo(String id) {
		if (Util.strIsEmpty(id)) {
			return new ReplyInfo<>(Constants.WARN_INVALID, "redo");
		}
		ReplyInfo<Object> bd = this.getBatchDispatcher(id);
		if (bd.isSuccess()) {
			int result = ((BatchDispatcher) bd.getData()).redo(id);
			return ReplyInfo.success(result);
		}
		return ReplyInfo.error(Constants.ERROR_NOTFOUND,"dispatcher");
	}

	@RequestMapping("/cancel.do")
	@Authorized(code = "batch.execution.cancel")
	public ReplyInfo<Object> cancel(String id, boolean force) {
		ReplyInfo<Object> bd = this.getBatchDispatcher(id);
		if (bd.isSuccess()) {
			int result = ((BatchDispatcher) bd.getData()).cancel(id, force);
			return ReplyInfo.success(result);
		}
		return ReplyInfo.FAILED;
	}

	@RequestMapping("/delete.do")
	@Authorized(code = "batch.execution.delete")
	public ReplyInfo<Object> delete(String id) {
		batchExeBiz.delete(id);
		return ReplyInfo.SUCCESS;
	}

	@RequestMapping("/list.do")
	@Authorized(code = "batch.execution.list")
	public ReplyInfo<Object> list(String infoId, String startTime, String endTime, int pageNo, int pageSize) {
		PagedResult<BatchExecution> pr = batchExeBiz.list(infoId, startTime, endTime, pageNo, pageSize);
		return ReplyInfo.success(pr);
	}

	@RequestMapping("/get.do")
	@Authorized(code = "batch.execution.get")
	public ReplyInfo<Object> get(String id) {
		if (Util.strIsEmpty(id)) {
			return new ReplyInfo<>(Constants.WARN_INVALID, "get");
		}
		BatchExecution o = batchExeBiz.get(id);
		return ReplyInfo.success(o);
	}

	@RequestMapping("/refresh.do")
	@Authorized(code = "batch.execution.list")
	public ReplyInfo<Object> refresh(String keys) {
		String[] ids = keys.trim().split(",");
		List<BatchExecution> list = batchExeBiz.list(ids);
		return ReplyInfo.success(list);
	}

	@RequestMapping("/executing.do")
	@Authorized(code = "batch.execution.list")
	public ReplyInfo<Object> executing(int pageNo, int pageSize) {
		PagedResult<Object[]> oPr = batchExeBiz.listExecuting(pageNo, pageSize);
		List<Object[]> oLt = oPr.getList();
		List<Map<String, Object>> rLt = new ArrayList<Map<String, Object>>(oLt.size());
		for (Object[] oa : oLt) {
			BatchExecution exe = (BatchExecution) oa[0];
			BatchInfo info = (BatchInfo) oa[1];
			Map<String, Object> map = new HashMap<String, Object>();
			BeanUtil.fillMapWithObject(map, exe);
			map.put("name", info.getName());
			rLt.add(map);
		}
		PagedResult<Map<String, Object>> rPr = new PagedResult<>(oPr.getTotal(), rLt, pageNo, pageSize);
		return ReplyInfo.success(rPr);
	}
}